﻿using Microsoft.AspNetCore.Mvc;
using Minio.DataModel.Args;
using Minio;

namespace B.S.XZYData.Api.Wrter.Controllers
{
    /// <summary>
    /// minio
    /// </summary>
        [Route("api/[controller]/[action]")]
        [ApiController]
        public class FileUploadController : ControllerBase
        {
            private readonly IMinioClient _minioClient;
            private string bucketName = "images";

            public FileUploadController()
            {
                _minioClient = new MinioClient()
                    .WithEndpoint("10.223.10.34:9000")       // MinIO 服务器的端点地址为 "10.31.60.18:9000"
                    .WithCredentials("admin", "admin123")   // MinIO 服务器连接所需的凭据，包括用户名和密码
                    .WithSSL(false)                         // MinIO 服务器是否启用 SSL 加密通信
                    .Build();                               // MinIO 服务器配置完成，构建 MinioClient 实例
            }

            [HttpGet]
            public async Task<IActionResult> ListBuckets()
            {
                // ListBucketsAsync() 来获取 MinIO 服务器上的所有存储桶 (buckets
                // ConfigureAwait(false) 的作用是防止异步操作回到调用线程上继续执行，以避免死锁。
                var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
                return Ok(buckets);
            }

            /// <summary>
            /// 上传单个文件
            /// </summary>
            /// <param name="file"></param>
            /// <returns></returns>
            [HttpPost]
            public async Task<IActionResult> UploadFile(IFormFile file)
            {
                // 检查桶是否存在
                var beArgs = new BucketExistsArgs()
                    .WithBucket(bucketName);
                bool found = await _minioClient.BucketExistsAsync(beArgs);

                // 如果桶不存在，则创建桶
                if (!found)
                {
                    var mbArgs = new MakeBucketArgs()
                        .WithBucket(bucketName);
                    await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
                }

                // 获取文件名，加入全球唯一标识
                var objectName = $"{Guid.NewGuid()}_{file.FileName}";

                // 使用流数据上传文件
                var putArgs = new PutObjectArgs()
                    .WithBucket(bucketName)
                    .WithObject(objectName)
                    .WithStreamData(file.OpenReadStream())
                    .WithContentType(file.ContentType)
                    .WithObjectSize(file.Length);
                await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

                // 直接拼接公开URL
                var url = $"http://10.223.10.34:9000/{bucketName}/{objectName}";
                return Ok(url);
            }

            /// <summary>
            /// 上传多个文件
            /// </summary>
            /// <param name="formFiles">要上传的文件集合</param>
            /// <returns>返回上传成功的文件名列表</returns>
            [HttpPost]
            public async Task<IActionResult> UploadFiles(IFormFileCollection formFiles)
            {
                // 检查存储桶是否存在
                var beArgs = new BucketExistsArgs()
                    .WithBucket(bucketName);
                bool found = await _minioClient.BucketExistsAsync(beArgs);

                // 如果桶不存在则创建
                if (!found)
                {
                    var mbArgs = new MakeBucketArgs()
                        .WithBucket(bucketName);
                    await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
                }

                var uploadedFileUrls = new List<string>();
                foreach (var formFile in formFiles)
                {
                    using var stream = formFile.OpenReadStream();

                    // 获取文件名，加入全球唯一标识
                    var objectName = $"{Guid.NewGuid()}_{formFile.FileName}";

                    // 上传文件到MinIO
                    var putArgs = new PutObjectArgs()
                        .WithBucket(bucketName)
                        .WithObject(objectName)
                        .WithStreamData(stream)
                        .WithContentType(formFile.ContentType)
                        .WithObjectSize(stream.Length);

                    await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

                    // 直接拼接公开URL
                    var url = $"http://10.223.10.34:9000/{bucketName}/{objectName}";
                    uploadedFileUrls.Add(url);
                }

                // 以逗号分隔字符串返回
                var result = string.Join(",", uploadedFileUrls);
                return Ok(result);
            }
        }
}
